const sourceData = [1, [2, 3, [4, 5, [6, 7, 8, [9, 10]]]]]

function flatByFor(arr) {
  const res = []

  for (let i = 0; i < arr.length; i++) {
    Array.isArray(arr[i]) ? res.push(...flatByFor(arr[i])) : res.push(arr[i])
  }

  return res
}

function flatByForEach(arr) {
  const res = []

  arr.forEach(item => {
    Array.isArray(item) ? res.push(...flatByForEach(item)) : res.push(item)
  })

  return res
}

function flatByReduce(arr) {
  return arr.reduce((acc, cur) => {
    return acc.concat(Array.isArray(cur) ? flatByReduce(cur) : cur)
  }, [])
}

function flatByWhileSome(arr) {
  while (arr.some(item => Array.isArray(item))) {
    arr = [].concat(...arr)
  }

  return arr
}

function flatByWhileShift(arr) {
  const res = []
  const stack = [...arr] // 或 arr.slice()

  while (stack.length) {
    const next = stack.shift()
    Array.isArray(next) ? stack.push(...next) : res.push(next)
  }

  return res
}

// console.log(JSON.stringify(sourceData.flat()))
console.log(sourceData, flatByReduce(sourceData))

function deepFlatByFor(arr, depth = Infinity) {
  const res = []

  for (let i = 0; i < arr.length; i++) {
    Array.isArray(arr[i]) && depth > 0
      ? res.push(...deepFlatByFor(arr[i], depth - 1))
      : res.push(arr[i])
  }

  return res
}

function deepFlatByForEach(arr, depth = Infinity) {
  const res = []

  arr.forEach(item => {
    Array.isArray(item) && depth > 0
      ? res.push(...deepFlatByForEach(item, depth - 1))
      : res.push(item)
  })

  return res
}

function deepFlatByReduce(arr, depth = Infinity) {
  return depth > 0
    ? arr.reduce(
        (acc, cur) =>
          acc.concat(
            Array.isArray(cur) ? deepFlatByReduce(cur, depth - 1) : cur
          ),
        []
      )
    : arr.slice()
}

function deepFlatByWhileSome(arr, depth = Infinity) {
  while (arr.some(item => Array.isArray(item)) && depth > 0) {
    arr = [].concat(...arr)
    depth--
  }

  return arr
}

// console.log(deepFlatByFor(sourceData, 2))
